package dice.sinanya.dice.game;

import dice.sinanya.dice.MakeNickToSender;
import dice.sinanya.entity.EntityDeckList;
import dice.sinanya.entity.EntityTypeMessages;
import dice.sinanya.exceptions.NotEnableBySimpleException;
import dice.sinanya.exceptions.NotEnableException;
import dice.sinanya.exceptions.NotEnableInGroupException;
import dice.sinanya.exceptions.NotMasterException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nlpcn.commons.lang.util.StringUtil;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import static dice.sinanya.system.MessagesBanList.groupSwitchHashMap;
import static dice.sinanya.system.MessagesTag.*;
import static dice.sinanya.tools.checkdata.CheckPower.checkMaster;
import static dice.sinanya.tools.getinfo.Deck.*;
import static dice.sinanya.tools.getinfo.GetMessagesProperties.*;
import static dice.sinanya.tools.getinfo.GetNickName.getNickName;
import static dice.sinanya.tools.getinfo.MyDownLoadFromUrl.downloadFile;
import static dice.sinanya.tools.makedata.Sender.sender;
import static dice.sinanya.tools.makedata.StringFormatById.stringFormatById;

/**
 * @author SitaNya
 * 日期: 2019-08-22
 * 电子邮箱: sitanya@qq.com
 * 维护群(QQ): 162279609
 * 有任何问题欢迎咨询
 * 类说明:
 */
public class Deck implements MakeNickToSender {
    private static final Logger logger = LogManager.getLogger(Deck.class.getName());
    private final EntityTypeMessages entityTypeMessages;

    public Deck(EntityTypeMessages entityTypeMessages) {
        this.entityTypeMessages = entityTypeMessages;
    }

    public void get() throws NotEnableException, NotEnableInGroupException, NotEnableBySimpleException, IOException {
        checkEnable();
        String tag = TAG_DECK_GET;
        String msg = entityTypeMessages.getMsgGet().getMsg().trim().replaceFirst(tag.substring(0, tag.length() - 2), "").trim();
        String deckType;
        String type;
        if (msg.contains(" ")) {
            deckType = msg.split(" ")[0];
            type = msg.split(" ")[1];
        } else {
            deckType = msg;
            type = "default";
        }
        String result = getDeck(entityTypeMessages, deckType, type).replace("【name】", getNickName(entityTypeMessages));
        sender(entityTypeMessages, result);
    }

    public void help() throws NotEnableException, NotEnableInGroupException, NotEnableBySimpleException, UnsupportedEncodingException {
        checkEnable();
        HashMap<String, ArrayList<String>> deckHelp = getDeckHelp();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(entitySystemProperties.getDeckListShow(entityTypeMessages.getFromGroupString())).append(":");
        for (Map.Entry<String, ArrayList<String>> entry : deckHelp.entrySet()) {
            stringBuilder.append("\n").append(entry.getKey()).append(",其子命令如下:");
            for (String type : entry.getValue()) {
                if (!type.equals("default")) {
                    stringBuilder.append("\n\t").append(".deck ").append(type);
                }
            }
        }
        sender(entityTypeMessages, stringBuilder.toString());
    }

    private void checkEnable() throws NotEnableException, NotEnableInGroupException, NotEnableBySimpleException {
        if (!entityGame.isDeck()) {
            throw new NotEnableException(entityTypeMessages);
        }

        if (groupSwitchHashMap.containsKey(entityTypeMessages.getFromGroup()) && !groupSwitchHashMap.get(entityTypeMessages.getFromGroup()).isDeck()) {
            throw new NotEnableInGroupException(entityTypeMessages);
        }

        if (groupSwitchHashMap.containsKey(entityTypeMessages.getFromGroup()) && groupSwitchHashMap.get(entityTypeMessages.getFromGroup()).isSimple()) {
            throw new NotEnableBySimpleException(entityTypeMessages);
        }
    }

    public void list() throws UnsupportedEncodingException, NotMasterException {
        checkMaster(entityTypeMessages);
        ArrayList<EntityDeckList> internetDeck = getInternetDeck();
        ArrayList<EntityDeckList> hasDeck = getHasDeckList();
        ArrayList<String> result = new ArrayList<>();
        result.add("当前持有牌堆列表为:");
        for (EntityDeckList entityDeckList : hasDeck) {
            result.add(entityDeckList.toString());
        }
        result.add("牌堆市场列表为:");
        for (EntityDeckList entityDeckList : internetDeck) {
            result.add(entityDeckList.toString());
        }
        sender(entityTypeMessages, StringUtil.joiner(result, "\n"));
    }

    public void install() throws IOException, NotMasterException {
        checkMaster(entityTypeMessages);
        String tag = TAG_DECK_INSTALL;
        String msg = entityTypeMessages.getMsgGet().getMsg().trim().replaceFirst(tag.substring(0, tag.length() - 2), "").trim();
        if (deckInInternet(msg)) {
            downLoadDeck(msg);
        } else {
            sender(entityTypeMessages, "未找到此牌堆文件:\t" + msg);
        }
    }

    public void remove() throws UnsupportedEncodingException, NotMasterException {
        checkMaster(entityTypeMessages);
        String tag = TAG_DECK_REMOVE;
        String msg = entityTypeMessages.getMsgGet().getMsg().trim().replaceFirst(tag.substring(0, tag.length() - 2), "").trim();
        if (deckInHas(msg)) {
            deleteDeck(msg);
        } else {
            sender(entityTypeMessages, "未找到此牌堆文件:\t" + msg);
        }
    }

    private void downLoadDeck(String deck) throws IOException {
        String dir = entitySystemProperties.getSystemDir("0");
        File deckDir = new File(URLDecoder.decode(dir + File.separator + "deck", "UTF-8"), deck);
        boolean deckDirExists = deckDir.getParentFile().exists() && deckDir.getParentFile().isDirectory();
        if (!deckDirExists) {
            if (!deckDir.getParentFile().mkdirs()) {
                throw new IOException(stringFormatById("目录%s建立失败", deckDir.getParentFile().getPath()));
            }
        }
        boolean newDeckExists;
        long deckSize = new URL("https://deck-1256090486.file.myqcloud.com/" + java.net.URLEncoder.encode(deck, "utf-8")).openConnection().getContentLength();
        try {
            downloadFile("https://deck-1256090486.file.myqcloud.com/" + java.net.URLEncoder.encode(deck, "utf-8"), deckDir, deckSize, entityTypeMessages);
            newDeckExists = deckDir.exists();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            sender(entityTypeMessages, "安装失败，请重新执行命令");
            return;
        }

        if (newDeckExists && deckDir.length() == deckSize) {
            sender(entityTypeMessages, "安装成功，请使用.deck help查看");
        } else {
            File deleteFile = new File(URLDecoder.decode(deckDir.getPath() + File.separator + deck, "UTF-8"));
            if (deleteFile.exists() && deleteFile.isFile()) {
                if (!deleteFile.delete()) {
                    throw new IOException(stringFormatById("目录%s删除失败", deleteFile.getPath()));
                }
            }
            sender(entityTypeMessages, "安装失败，请至服务器手工操作或重新运行命令");
        }
    }

    private void deleteDeck(String deck) {
        try {
            if (!new File(URLDecoder.decode(entitySystemProperties.getSystemDir("0") + File.separator + "deck" + File.separator + deck, "UTF-8")).delete()) {
                sender(entityTypeMessages, "卸载失败，请到服务器手工操作");
            } else {
                sender(entityTypeMessages, "卸载成功");
            }
        } catch (UnsupportedEncodingException unsupportedEncodingException) {
            logger.error(unsupportedEncodingException.getMessage(), unsupportedEncodingException);
        }
    }
}
